package com.mazarine.components.videoplayer 
{
	import com.mazarine.components.videoplayer.IPlayer;
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.AsyncErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.NetStatusEvent;
	import flash.events.ProgressEvent;
	import flash.media.SoundTransform;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.net.URLRequest;

	public class Player extends Sprite implements IPlayer
	{
		// STREAM
		private var _connection:NetConnection;
		private var _stream:NetStream;	
		private var _soundTransfo:SoundTransform;
		//PARAMS
		private var _video:Video;		
		private var _duration:Number;		
		private var _poster :String ="";
		private var _posterLoader :Loader ;
		private var _smooth:Boolean = true;
		private var _autoPlay:Boolean;
		private var _autoLoop:Boolean;		
		private var _volume:Number=1;
		private var _src:String;	
		private var _muted :Boolean = false;
		private var _videoW: Number = 160;
		private var _videoH : Number = 90;
		private var _sw:Number;
		private var _sh:Number;
		private var _isPlaying:Boolean;
		
		public function Player(_videoUrl :String = "video.flv", _poster:String = "image.jg" , _loop:Boolean = true , _autoPlay : Boolean =true) 
		{					
			_connection = new NetConnection();
			_connection.connect(null);

			_stream = new NetStream(_connection);
			_stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
			_stream.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);

			var client: Object 		= new Object();
				client.onMetaData	= metaDataHandler;
				client.onCuePoint 	= cuePointHandler;
			
			_stream.client = client;
			
			_video = new Video();
			_video.attachNetStream(_stream);
			_video.smoothing = _smooth;
			_video.width = _videoW
			_video.height = _videoH
			addChild(_video);
			
			_soundTransfo = _stream.soundTransform;
			volume = 1;
		
			addEventListener(Event.ADDED_TO_STAGE, init)
			
			src = _videoUrl;
			poster = _poster;
			autoLoop = _loop
			autoPlay = _autoPlay
			
			trace("[Player.Player] "+_videoUrl , _poster , _autoLoop , _autoPlay);
			launch()
		}
			
		/////////////////////////////////////////////////////
		///////////////////		INTERFACE
		/////////////////////////////////////////////////////		
		public function play():void 
		{
			trace("[Player.play] ");
			_stream.resume()
			_isPlaying = true;
		}
		
		public function pause():void 
		{
			trace("[Player.pause] ");
			_stream.pause();
			_isPlaying = false;
		}
		
		public function stop():void 
		{
			_stream.seek(0);
			_stream.pause();
			_isPlaying = false;
		}
		
		public function togglePlayPause():void 
		{
			if (_isPlaying) pause();
			else play();			
		//	trace("[Player.togglePlayPause] "+_isPlaying);
		}
		
		public function toggleMute():void 
		{
			if (!_muted) setVolume(0);			
			else setVolume(_volume);			
			_muted = !_muted;
		}
		
		public function seek(seekTime:Number):void 
		{
			_stream.seek(seekTime);
		}
		
		public function resize(w:Number, h:Number):void 
		{			
			//trace("[Player.resize] " + w , h , _videoW , _videoH);			
			var ratio : Number = _videoW / _videoH ; 
			_video.width 	= w;			
			_video.height 	= w  / ratio;	
			
			if (_posterLoader)
			{
				var ratioLoader:Number = _posterLoader.width / _posterLoader.height;
				_posterLoader.width 	= w;			
				_posterLoader.height 	= w  / ratioLoader;	
			}
			_sw = w;
			_sh = h;
		}
		
		public function set src(src:String):void 
		{
			_src = src;			
		}
		
		public function set autoPlay(autoplay:Boolean):void 
		{
			_autoPlay = autoplay  ;
		}
		
		public function set volume(vol:Number):void 
		{
			//trace("[Player.volume] "+vol);
			_volume 				= vol;		
			setVolume(_volume);			
		}
		
		public function set autoLoop(autoLoop:Boolean):void 
		{
			_autoLoop = autoLoop ; 
		}
		
		public function get duration():Number
		{
			return _duration ;
		}
		
		public function get time():Number 
		{
			return _stream.time;
		}
		
		
		public function set poster(url:String):void 
		{
			_poster = url;
		}
		
		/////////////////////////////////////////////////////
		///////////////////		PRIVATE
		/////////////////////////////////////////////////////
		private function init(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
		}
			
		private function setVolume(_volume : Number):void 
		{
			_soundTransfo.volume 	= _volume;
			_stream.soundTransform 	= _soundTransfo;
		}
		
		private function metaDataHandler(data : Object):void 
		{
			_duration = data.duration;
			if( data.width) _videoW = data.width;
			if( data.height)_videoH = data.height;
			dispatchEvent(new PlayerEvent(PlayerEvent.DURATION_RECEIVED));			
			resize(_sw , _sh)
			trace("[Player.metaDataHandler] " + _duration , _videoW , _videoH );
		}
		
		private function launch():void
		{
			_stream.play(_src);			
			if (_autoPlay)_stream.resume();	
			else pause();
		}
		
		
		private function cuePointHandler(cuePoint:Object):void 
		{
			/*
			currentCuePoint = {name:cuePoint.name, time:cuePoint.time};
			dispatchEvent(new PlayerEvent(PlayerEvent.CUEPOINTS_RECEIVED));
			*/
		}
		
		private function asyncErrorHandler(event : AsyncErrorEvent):void 
		{		
			trace("[Player.asyncErrorHandler] >>>>>>>>>> "+AsyncErrorEvent.ASYNC_ERROR);
		}

		private function statusHandler(e : NetStatusEvent):void 
		{			
			trace("[Player.statusHandler] "+e.info.code);
			if (e.info.code == "NetStream.Play.Stop") 
			{
				_isPlaying = false;
				dispatchEvent(new PlayerEvent(PlayerEvent.VIDEO_END));							
				if (_autoLoop)  (e.target as NetStream).seek(0);
				else stop();
			}
			
			if (e.info.code == "NetStream.Play.Start") 
			{
				_isPlaying = true;
				dispatchEvent(new PlayerEvent(PlayerEvent.VIDEO_STARTS));			
			}
			if (e.info.code=="NetStream.Buffer.Empty") dispatchEvent(new PlayerEvent(PlayerEvent.BUFFER_EMPTY));				
			if (e.info.code=="NetStream.Buffer.Full") dispatchEvent(new PlayerEvent(PlayerEvent.BUFFER_FULL));
			if (e.info.code == "NetStream.Play.StreamNotFound") 
			{
				trace("[Player.statusHandler] STREAM NOT FOUND ! ");
				loadPoster()
			}
		}
		
		private function loadPoster():void
		{
			trace("[Player.loadPoster] "+_poster);
			
			if(_poster=="" || _poster =="null") return
			_posterLoader = new Loader()
			_posterLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,posterHandler)
			_posterLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,posterHandler)
			_posterLoader.load(new URLRequest(_poster))
			addChild(_posterLoader)
			
		}
		
		private function posterHandler(e:Event):void 
		{
			switch (e.type) 
			{
				case Event.COMPLETE:
				(_posterLoader.content as Bitmap).smoothing = true
				resize(_sw,_sh)
				break;
				
				case IOErrorEvent.IO_ERROR: trace("[Player.posterHandler] ERROR LOADING POSTER ! ");
				break;
			}
		}
	}	
}
